﻿using Abp.Authorization;
using Abp.IO.Extensions;
using Paas.App.Interface.Common;
using Paas.App.Interface.Common.Dtos;
using Paas.App.Interface.Common.Messages;
using Paas.Core;
using Paas.Core.Const;
using Paas.Core.Const.Enums.Common;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Basefr.App;
using System;
using System.IO;
using System.Linq;
using File = Paas.Core.Common.Entities.File;

namespace Paas.App.Common
{
    [Route("File")]
    [AbpAuthorize()]
    public class FileAppService : AppService, IFileAppService
    {
        private readonly IMainRepository<File> _fileRepo;
        private readonly IWebHostEnvironment _hostingEnvironment;

        public FileAppService(IMainRepository<File> fileRepo, IWebHostEnvironment hostingEnvironment)
        {
            _fileRepo = fileRepo;
            _hostingEnvironment = hostingEnvironment;
        }

        [HttpPost(nameof(UploadFile))]
        [RequestSizeLimit(10_000_000)]
        public UploadFileOutput UploadFile([FromForm] EnumFileType fileType, [FromForm] IFormFile file)
        {
            var fileExtend = file.FileName.Split('.').LastOrDefault();
            var physicalName = $"{Guid.NewGuid():N}.{fileExtend ?? ""}";

            var fileEntity = new File
            {
                Name = file.FileName,
                Code = Guid.NewGuid().ToString("N"),
                Type = fileType,
                MimeType = file.ContentType,
                PhysicalName = physicalName,
                Size = file.Length,
                PhysicalPath = physicalName,
                UploaderId = AbpSession.UserId,
            };

            var fileId = _fileRepo.InsertAndGetId(fileEntity);

            fileEntity.PhysicalPath = Path.Combine(_hostingEnvironment.ContentRootPath, SettingManager.GetSettingValue(SettingNames.FileUploadPath), fileEntity.CreationTime.ToString("yyyy-MM-dd"));

            if (!Directory.Exists(fileEntity.PhysicalPath))
            {
                Directory.CreateDirectory(fileEntity.PhysicalPath);
            }

            fileEntity.PhysicalName = $"{fileId}_{physicalName}";

            System.IO.File.WriteAllBytes(Path.Combine(fileEntity.PhysicalPath, fileEntity.PhysicalName), file.OpenReadStream().GetAllBytes());

            return new UploadFileOutput { Item = ObjectMapper.Map<FileDto>(fileEntity) };
        }

        [AbpAllowAnonymous]
        public virtual DownloadFileOutput DownloadFile(DownloadFileInput rq)
        {
            var file = _fileRepo.FirstOrDefault(rq.Id);
            var fileStream = System.IO.File.OpenRead(System.IO.Path.Combine(file.PhysicalPath, file.PhysicalName));

            return new DownloadFileOutput { Item = ObjectMapper.Map<FileDto>(file), FileStream = fileStream };
        }
    }
}

